package day4;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//通过反射编写一个任意对象调用任意方法
public class TestInvokeMethod {
    //method(方法名，形参class[])
    //method.invoke(对象，实参...)
    //参数1：调用方法的对象 参数2：方法名称
    //参数3：方法调用传递的实参
    //返回值：表示方法的返回值
    //arg:如果调用了带基本类型参数的方法 会自动装箱 导致方法不存在
    public static Object base(Object o,String name,Object ... params){
        Object value= null;
        try {
            Class c=o.getClass();
            Class[] args=new Class[params.length];
            for(int i=0;i<params.length;i++){
                args[i]=params[i].getClass();
            }
            Method m=c.getDeclaredMethod(name,args);
            m.setAccessible(true);
            value = m.invoke(o,params);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return value;
    }
    //bug:虽然搞定了基本类型参数的bug 但是如果方法重载了呢
    public static Object base2(Object o,String name,Object ... params){
        Class c=o.getClass();
        Class[] args=null;
        for(Method m:c.getDeclaredMethods()){
            if(m.getName().equals(name)){
                args=m.getParameterTypes();
            }
        }
        Object value= null;
        try {
            Method m=c.getDeclaredMethod(name,args);
            m.setAccessible(true);
            value = m.invoke(o,params);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return value;
    }
    public static void main(String[] args) {
        Student2 s2=new Student2();
        Object value=TestInvokeMethod.base(s2,"math",10,20);
        System.out.println(value);
        Teacher t=new Teacher();
        Object value2=TestInvokeMethod.base2(t,"sum",99,98);
        System.out.println(value2);
    }
}
